/*
* Copyright 2010 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/

package org.bookmarksframework.core.browser
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.external.ExternalInterface;
	
	import org.bookmarksframework.BookmarksConfig;
	
	[Event(name="change", type="flash.event.Event")]
	
	[Event(name="internalChange", type="flash.event.Event")]
	
	[Event(name="externalChange", type="flash.event.Event")]
	
	public class SWFAddressAdapter extends EventDispatcher implements IBrowserAdapter
	{
		protected var adoptee:Object;
		
		protected var config:BookmarksConfig;
		
		protected var pathQualifier:String = "/";
		
		protected var initialized:Boolean = false;
		
		protected var useStrictPath:Boolean = false;
		
		public function SWFAddressAdapter(adoptee:Object)
		{
			this.adoptee = adoptee;
		}
		
		public function get fragment():String
		{
			checkInitialization();
			return qualify(unescape(adoptee.getValue()));
		}
		
		public function set fragment(value:String):void
		{
			checkInitialization();
			adoptee.setValue(qualify(value));
		}
		
		public function get title():String
		{
			checkInitialization();
			return adoptee.getTitle();
		}
		
		public function set title(value:String):void
		{
			checkInitialization();
			adoptee.setTitle(value);
		}
		
		public function getURL():String
		{
			checkInitialization();
			return adoptee.getBaseURL();
		}
		
		public function initialize(config:BookmarksConfig, 
								   fragment:String="", title:String=""):void
		{
			if (!adoptee)
				throw new Error("Bookmarks Error: Adoptee can't be null.");
			
			this.config = config;
			useStrictPath = config.useStrictPath;
			adoptee.setStrict(config.useStrictPath);
			
			adoptee.addEventListener("change", changeHandler);
			adoptee.addEventListener("internalChange", internalChangeHandler);
			adoptee.addEventListener("externalChange", externalChangeHandler);
			checkInitialization();
			
			if (fragment)
				this.fragment = fragment;
			
			if (title)
				this.title = title;
		}
		
		public function isFragmentEmpty():Boolean
		{
			var fragment:String = this.fragment;
			return !fragment || (fragment == pathQualifier);
		}
		
		public function destroy():void
		{
			adoptee.removeEventListener("change", changeHandler);
			adoptee.removeEventListener("internalChange", internalChangeHandler);
			adoptee.removeEventListener("externalChange", externalChangeHandler);
			initialized = false;
			adoptee = null;
		}
		
		protected function changeHandler(event:Event):void
		{
			if (hasEventListener(BrowserAdapterEvents.CHANGE))
				dispatchEvent(new Event(BrowserAdapterEvents.CHANGE));
		}
		
		protected function internalChangeHandler(event:Event):void
		{
			if (hasEventListener(BrowserAdapterEvents.INTERNAL_CHANGE))
				dispatchEvent(new Event(BrowserAdapterEvents.INTERNAL_CHANGE));
		}
		
		protected function externalChangeHandler(event:Event):void
		{
			if (hasEventListener(BrowserAdapterEvents.EXTERNAL_CHANGE))
				dispatchEvent(new Event(BrowserAdapterEvents.EXTERNAL_CHANGE));
		}
		
		protected function qualify(fragment:String):String
		{
			if (useStrictPath && fragment.indexOf(pathQualifier) != 0)
				fragment = pathQualifier + fragment;
			
			return fragment;
		}
		
		private function checkInitialization():void
		{
			if (!initialized)
			{
				initialized = Boolean(ExternalInterface.call(
					'function(){return(typeof SWFAddress != "undefined");}'));
				if (!initialized)
					trace("Bookmarks Error: SWFAddress is not initialized.");
			}
		}
	}
}